package com.gqh.weather.service;

import com.alibaba.excel.EasyExcel;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gqh.weather.config.FileConfig;
import com.gqh.weather.config.MinioConfig;
import com.gqh.weather.domain.dto.ScoreTeacherAccount;
import com.gqh.weather.domain.dto.ScoreTeacherAccountConfig;
import com.gqh.weather.domain.dto.ScoreTeacherExportDTO;
import com.gqh.weather.domain.entity.PcSubtask;
import com.gqh.weather.exception.BusinessException;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @description 评分教师管理服务类
 * @author AI
 * @date 2025-09-21
 */
@Slf4j
@Service
public class ScoreTeacherService {

    @Autowired
    private PcSubtaskService pcSubtaskService;
    
    @Autowired
    private FileConfig fileConfig;

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConfig minioConfig;
    


    /**
     * 保存阅卷配置数据
     *
     * @param pcSubtaskId 机试子任务ID
     * @param configData 阅卷配置数据
     * @throws Exception 异常信息
     */
    public void saveConfig(Integer pcSubtaskId, String configData) throws Exception {
        // 获取PC子任务信息
        PcSubtask subtaskInfo = pcSubtaskService.getById(pcSubtaskId);
        if (subtaskInfo == null) {
            throw new Exception("机试任务不存在");
        }
        
        // 检查阅卷状态，如果不为0（未开始）则不能修改配置数据
        if (subtaskInfo.getYjState() != null && subtaskInfo.getYjState() != 0) {
            throw new Exception("已开始阅卷，无法修改配置数据");
        }
        
        // 检查阅卷任务类型，如果不为1（阅卷）则不能保存配置数据
        if (subtaskInfo.getType() == null || subtaskInfo.getType() != 1) {
            throw new Exception("阅卷任务为不阅卷");
        }
        
        // 保存阅卷配置数据
        boolean success = pcSubtaskService.setScoreTeacherConfig(pcSubtaskId, configData);
        if (!success) {
            throw new Exception("保存阅卷配置数据失败");
        }
        
        log.info("保存阅卷配置数据成功，机试子任务ID: {}", pcSubtaskId);
    }
    
    /**
     * 开始阅卷
     *
     * @param pcSubtaskId 机试子任务ID
     * @throws Exception 异常信息
     */
    public void beginScore(Integer pcSubtaskId) throws Exception {
        if (pcSubtaskId == null || pcSubtaskId == 0) {
            throw new BusinessException("pc_subtask_id参数错误");
        }
        
        // 获取PC子任务信息
        PcSubtask pcSubTaskInfo = pcSubtaskService.getById(pcSubtaskId);
        if (pcSubTaskInfo == null) {
            throw new BusinessException("机试任务不存在");
        }
        
        // 检查任务状态是否为已发布
        if (pcSubTaskInfo.getState() != null && pcSubTaskInfo.getState() != 1) {
            throw new BusinessException("无法操作，任务状态不为已发布状态");
        }
        
        // 检查考试时间是否已结束
        if (pcSubTaskInfo.getTaskPid() != null) {
            // 需要获取主任务来检查结束时间
            // 这里简化处理，假设任务信息中包含结束时间
            Long endAt = pcSubTaskInfo.getUpdatedTime(); // 使用更新时间作为示例
            if (endAt != null && endAt > Instant.now().getEpochSecond()) {
            throw new BusinessException("无法操作，考试时间尚未结束");
            }
        }
        
        // 检查阅卷状态是否为未开始
        if (pcSubTaskInfo.getYjState() != null && pcSubTaskInfo.getYjState() >= 1) {
            throw new BusinessException("无法操作，阅卷进行中或已结束");
        }
        
        // 设置阅卷状态为进行中
        boolean success = pcSubtaskService.setYjState(pcSubtaskId, 1);
        if (!success) {
            throw new Exception("开始阅卷失败");
        }
        
        log.info("开始阅卷成功，机试子任务ID: {}", pcSubtaskId);
    }
    
    /**
     * 开始复评
     *
     * @param pcSubtaskId 机试子任务ID
     * @throws Exception 异常信息
     */
    public void beginReview(Integer pcSubtaskId) throws Exception {
        if (pcSubtaskId == null || pcSubtaskId == 0) {
            throw new BusinessException("pc_subtask_id参数错误");
        }
        
        // 获取PC子任务信息
        PcSubtask pcSubTaskInfo = pcSubtaskService.getById(pcSubtaskId);
        if (pcSubTaskInfo == null) {
            throw new BusinessException("机试任务不存在");
        }
        
        // 检查任务状态是否为已发布
        if (pcSubTaskInfo.getYjState() != null && pcSubTaskInfo.getYjState() != 1) {
            throw new BusinessException("还未开始阅卷");
        }
        
        // 检查复评状态是否为未开始
        if (pcSubTaskInfo.getFpState() != null && pcSubTaskInfo.getFpState() >= 1) {
            throw new BusinessException("无法操作，复评进行中或已结束");
        }
        
        // 设置复评状态为进行中
        boolean success = pcSubtaskService.setFpState(pcSubtaskId, 1);
        if (!success) {
            throw new Exception("开始复评失败");
        }
        
        log.info("开始复评成功，机试子任务ID: {}", pcSubtaskId);
    }
    
    /**
     * 导出阅卷老师信息
     *
     * @param pcSubtaskId 机试子任务ID
     * @return 文件URL
     */
    public String export(Integer pcSubtaskId) throws Exception {
        // 获取PC子任务信息
        PcSubtask subtaskInfo = pcSubtaskService.getById(pcSubtaskId);
        if (subtaskInfo == null) {
            throw new BusinessException("机试任务不存在");
        }
        
        // 检查阅卷老师配置数据是否为空
        if (subtaskInfo.getScoreTeacher() == null || subtaskInfo.getScoreTeacher().isEmpty()) {
            throw new BusinessException("阅卷老师配置数据为空");
        }
        
        // 解析阅卷老师账号
        ObjectMapper objectMapper = new ObjectMapper();
        ScoreTeacherAccountConfig stCfg = objectMapper.readValue(subtaskInfo.getScoreTeacher(), ScoreTeacherAccountConfig.class);
        
        Set<String> qids = new HashSet<>();
        Map<String, List<ScoreTeacherAccountConfig.ScoreTeacherAccount>> qidAccountCfg = new java.util.HashMap<>();
        
        // 处理Start配置
        if (stCfg.getStart() != null) {
            for (Map.Entry<String, List<ScoreTeacherAccountConfig.ScoreTeacherAccount>> entry : stCfg.getStart().entrySet()) {
                String qid = entry.getKey();
                List<ScoreTeacherAccountConfig.ScoreTeacherAccount> acc = entry.getValue();
                if (!qidAccountCfg.containsKey(qid)) {
                    qids.add(qid);
                    qidAccountCfg.put(qid, new ArrayList<>());
                }
                qidAccountCfg.get(qid).addAll(acc);
            }
        }
        
        // 处理Review配置
        if (stCfg.getReview() != null) {
            for (Map.Entry<String, List<ScoreTeacherAccountConfig.ScoreTeacherAccount>> entry : stCfg.getReview().entrySet()) {
                String qid = entry.getKey();
                List<ScoreTeacherAccountConfig.ScoreTeacherAccount> acc = entry.getValue();
                if (!qidAccountCfg.containsKey(qid)) {
                    qids.add(qid);
                    qidAccountCfg.put(qid, new ArrayList<>());
                }
                qidAccountCfg.get(qid).addAll(acc);
            }
        }
        
        // 处理End配置
        if (stCfg.getEnd() != null) {
            for (Map.Entry<String, List<ScoreTeacherAccountConfig.ScoreTeacherAccount>> entry : stCfg.getEnd().entrySet()) {
                String qid = entry.getKey();
                List<ScoreTeacherAccountConfig.ScoreTeacherAccount> acc = entry.getValue();
                if (!qidAccountCfg.containsKey(qid)) {
                    qids.add(qid);
                    qidAccountCfg.put(qid, new ArrayList<>());
                }
                qidAccountCfg.get(qid).addAll(acc);
            }
        }
        
        // 准备导出数据
        List<ScoreTeacherExportDTO> exportData = new ArrayList<>();
        for (String qid : qids) {
            List<ScoreTeacherAccountConfig.ScoreTeacherAccount> accounts = qidAccountCfg.get(qid);
            if (accounts != null) {
                for (ScoreTeacherAccountConfig.ScoreTeacherAccount account : accounts) {
                    ScoreTeacherExportDTO dto = new ScoreTeacherExportDTO();
                    dto.setAccount(account.getAcc());
                    dto.setPassword(String.valueOf(account.getPwd()));
                    exportData.add(dto);
                }
            }
        }
        
        // 生成文件名
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss"));
        String fileName = "阅卷老师信息表_" + timestamp + ".xlsx";
        
        // 生成文件路径
        Path exportDir = Paths.get(fileConfig.getExportDir());
        if (!Files.exists(exportDir)) {
            Files.createDirectories(exportDir);
        }
        
        String filePath = fileConfig.getExportDir() + "/" + fileName;

        File file = new File(filePath);

        // 使用EasyExcel写入文件
        EasyExcel.write(file, ScoreTeacherExportDTO.class)
                .sheet("Sheet1")
                .doWrite(exportData);
        
        // 上传文件到MinIO的temp存储桶
        String objectName = fileName;

        try (FileInputStream fis = new FileInputStream(file)) {
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(minioConfig.getTemp()) // 使用现有的存储桶
                            .object(objectName)
                            .stream(fis, file.length(), -1)
                            .contentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
                            .build()
            );
        }

        // 删除本地文件
        file.delete();

        // 返回MinIO文件URL
        return "/files/" + minioConfig.getTemp() + "/" + objectName;
    }
    
}